import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Order } from './entities/order.entity';
import { CreateOrderDto } from './dto/create-order.dto';
import { QueryOrderDto } from './dto/query-order.dto';
import { Goods } from '../goods/entities/goods.entity';
import { Address } from '../address/entities/address.entity';

@Injectable()
export class OrderService {
  @InjectRepository(Order)
  private orderRepository: Repository<Order>;

  @InjectRepository(Goods)
  private goodsRepository: Repository<Goods>;

  @InjectRepository(Address)
  private addressRepository: Repository<Address>;

  async create(createOrderDto: CreateOrderDto, userId: number) {
    const { goodsId, addressId } = createOrderDto;

    const goods = await this.goodsRepository.findOne({
      where: { id: goodsId },
      relations: ['seller'],
    });

    if (!goods) {
      throw new HttpException('商品不存在', HttpStatus.BAD_REQUEST);
    }

    if (goods.status !== 1) {
      throw new HttpException('商品已下架或已售出', HttpStatus.BAD_REQUEST);
    }

    if (goods.seller.id === userId) {
      throw new HttpException('不能购买自己的商品', HttpStatus.BAD_REQUEST);
    }

    const address = await this.addressRepository.findOne({
      where: { id: addressId, user: { id: userId } },
    });

    if (!address) {
      throw new HttpException('收货地址不存在', HttpStatus.BAD_REQUEST);
    }

    const order = new Order();
    order.orderNo = this.generateOrderNo();
    order.amount = goods.price;
    order.buyer = { id: userId } as any;
    order.seller = goods.seller;
    order.goods = goods;
    order.address = address;

    try {
      await this.orderRepository.save(order);
      return '创建成功';
    } catch (e) {
      throw new HttpException('创建失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  async findAll(queryOrderDto: QueryOrderDto, userId: number) {
    const {
      pageNum = 1,
      pageSize = 10,
      status,
      asBuyer = true,
    } = queryOrderDto;

    const skipCount = (pageNum - 1) * pageSize;
    const condition: Record<string, any> = {};

    if (status) {
      condition.status = status;
    }

    if (asBuyer) {
      condition.buyer = { id: userId };
    } else {
      condition.seller = { id: userId };
    }

    const [orders, total] = await this.orderRepository.findAndCount({
      where: condition,
      skip: skipCount,
      take: pageSize,
      relations: ['buyer', 'seller', 'goods', 'address'],
      order: {
        createTime: 'DESC',
      },
    });

    return {
      orders,
      total,
    };
  }

  async findOne(id: number, userId: number) {
    const order = await this.orderRepository.findOne({
      where: [
        { id, buyer: { id: userId } },
        { id, seller: { id: userId } },
      ],
      relations: ['buyer', 'seller', 'goods', 'address'],
    });

    if (!order) {
      throw new HttpException('订单不存在', HttpStatus.BAD_REQUEST);
    }

    return order;
  }

  async pay(id: number, userId: number) {
    const order = await this.orderRepository.findOne({
      where: { id, buyer: { id: userId } },
      relations: ['goods'],
    });

    if (!order) {
      throw new HttpException('订单不存在', HttpStatus.BAD_REQUEST);
    }

    if (order.status !== 1) {
      throw new HttpException('订单状态错误', HttpStatus.BAD_REQUEST);
    }

    order.status = 2;
    order.payTime = new Date();
    order.goods.status = 2;

    try {
      await this.orderRepository.save(order);
      await this.goodsRepository.save(order.goods);
      return '支付成功';
    } catch (e) {
      throw new HttpException('支付失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  async ship(id: number, userId: number) {
    const order = await this.orderRepository.findOne({
      where: { id, seller: { id: userId } },
    });

    if (!order) {
      throw new HttpException('订单不存在', HttpStatus.BAD_REQUEST);
    }

    if (order.status !== 2) {
      throw new HttpException('订单状态错误', HttpStatus.BAD_REQUEST);
    }

    order.status = 3;
    order.shipTime = new Date();

    try {
      await this.orderRepository.save(order);
      return '发货成功';
    } catch (e) {
      throw new HttpException('发货失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  async receive(id: number, userId: number) {
    const order = await this.orderRepository.findOne({
      where: { id, buyer: { id: userId } },
    });

    if (!order) {
      throw new HttpException('订单不存在', HttpStatus.BAD_REQUEST);
    }

    if (order.status !== 3) {
      throw new HttpException('订单状态错误', HttpStatus.BAD_REQUEST);
    }

    order.status = 4;
    order.completeTime = new Date();

    try {
      await this.orderRepository.save(order);
      return '确认收货成功';
    } catch (e) {
      throw new HttpException('确认收货失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  async cancel(id: number, userId: number) {
    const order = await this.orderRepository.findOne({
      where: [
        { id, buyer: { id: userId } },
        { id, seller: { id: userId } },
      ],
      relations: ['goods'],
    });

    if (!order) {
      throw new HttpException('订单不存在', HttpStatus.BAD_REQUEST);
    }

    if (order.status !== 1) {
      throw new HttpException('订单状态错误', HttpStatus.BAD_REQUEST);
    }

    order.status = 5;
    order.goods.status = 1;

    try {
      await this.orderRepository.save(order);
      await this.goodsRepository.save(order.goods);
      return '取消成功';
    } catch (e) {
      throw new HttpException('取消失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  private generateOrderNo() {
    const now = new Date();
    const year = now.getFullYear().toString().slice(-2);
    const month = (now.getMonth() + 1).toString().padStart(2, '0');
    const day = now.getDate().toString().padStart(2, '0');
    const random = Math.floor(Math.random() * 1000000)
      .toString()
      .padStart(6, '0');
    return `${year}${month}${day}${random}`;
  }
}
